package com.soul.proxy;

import com.soul.exceptions.SoulRemoteException;
import com.soul.interceptor.Interceptor;
import com.soul.net.http.HttpRequest;
import com.soul.net.http.HttpResponse;
import com.soul.net.http.HttpService;
import com.soul.parse.ParseRequest;
import com.soul.parse.ParseResponse;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 请求代理
 */
public class HttpInterface implements InvocationHandler {
    
    private HttpService service;
    private ParseRequest parseRequest = new ParseRequest(); 
    private ParseResponse parseResponse = new ParseResponse(); 
    
    private List<Interceptor> interceptors;
    
    private List<Interceptor> preExecutedInterceptor = new ArrayList<>();
    private List<Interceptor> postExecutedInterceptor = new ArrayList<>();

    public HttpInterface(HttpService service,List<Interceptor> interceptors) {
        this.service = service;
        this.interceptors = interceptors;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        HttpRequest request = parseRequest.parse(method, args);
        preInterceptor(request);
        HttpResponse response = service.sendRequest(request);
        postRequest(request,response);
        return parseResponse.parse(method,response);
    }

    /**
     * 前置拦截调用
     * @param request
     * @param response
     */
    private void postRequest(HttpRequest request, HttpResponse response) {
        if (interceptors != null && interceptors.size() > 0) {
            for (Interceptor interceptor : interceptors) {
                if (preExecutedInterceptor.contains(interceptor)){
                    continue;
                }
                preExecutedInterceptor.add(interceptor);
                interceptor.postRequest(request,response);
            }
        }
    }

    /**
     * 后置拦截调用
     * @param request
     */
    private void preInterceptor(HttpRequest request) {
        if (interceptors != null && interceptors.size() > 0) {
            for (Interceptor interceptor : interceptors) {
                if (postExecutedInterceptor.contains(interceptor)){
                    continue;
                }
                postExecutedInterceptor.add(interceptor);
                interceptor.preRequest(request);
            }
        }
    }
}
